package pl.freetimetool.domain;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.validation.constraints.Size;

import org.hibernate.validator.constraints.Email;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.DateTimeFormat.ISO;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;

@Entity
@Table(name = "account")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Account extends User implements UserDetails {


	/**
	 * 
	 */
	private static final long serialVersionUID = 7407989106607054991L;
	
	public Account(){
		super("NONE", "NONE", false, false,false, false, new ArrayList<GrantedAuthority>());
	}

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	Integer id;

	@Size(min = 2, max = 25)
	private String name;

	@Size(min = 2, max = 30)
	private String surname;

	@Size(min = 5, max = 30)
	private String username;

	@Size(min = 5, max = 50)
	@Email
	private String emailAdress;

	private Integer numberOfFreeDays;

	@Size(min = 9, max = 15)
	private String telephoneNumber;

	@Size(min = 5, max = 20)
	private String password;

	@Transient
	private String repeatedPassword;

	@DateTimeFormat(iso = ISO.DATE_TIME)
	Date addedDate = new Date();

	@OneToMany(cascade = CascadeType.ALL, mappedBy = "account", fetch = FetchType.EAGER, targetEntity = AccountRole.class)
	List<AccountRole> accountRole = new ArrayList<AccountRole>();

	public Integer getId() {
		return this.id;
	}

	public void setId(final Integer id) {
		this.id = id;
	}

	public String getName() {
		return this.name;
	}

	public void setName(final String name) {
		this.name = name;
	}

	public String getPassword() {
		return this.password;
	}

	public void setPassword(final String password) {
		this.password = password;
	}

	public String getRepeatedPassword() {
		return this.repeatedPassword;
	}

	public void setRepeatedPassword(final String repeatedPassword) {
		this.repeatedPassword = repeatedPassword;
	}

	public Date getAddedDate() {
		return this.addedDate;
	}

	public void setAddedDate(final Date addedDate) {
		this.addedDate = addedDate;
	}

	public List<AccountRole> getAccountRole() {
		return this.accountRole;
	}

	public void setAccountRole(final List<AccountRole> accountRole) {
		for (final AccountRole ar : accountRole) {
			this.addAccountRole(ar);
		}
	}

	public void addAccountRole(final AccountRole accountRole) {
		if (!this.accountRole.contains(accountRole)) {
			accountRole.setAccount(this);
			this.accountRole.add(accountRole);
		}
	}

	public String getSurname() {
		return this.surname;
	}

	public void setSurname(final String surname) {
		this.surname = surname;
	}

	public String getEmailAdress() {
		return this.emailAdress;
	}

	public void setEmailAdress(final String emailAdress) {
		this.emailAdress = emailAdress;
	}

	public Integer getNumberOfFreeDays() {
		return this.numberOfFreeDays;
	}

	public void setNumberOfFreeDays(final Integer numberOfFreeDays) {
		this.numberOfFreeDays = numberOfFreeDays;
	}

	public String getTelephoneNumber() {
		return this.telephoneNumber;
	}

	public void setTelephoneNumber(final String telephoneNumber) {
		this.telephoneNumber = telephoneNumber;
	}

	public String getUsername() {
		return this.username;
	}

	public void setUsername(final String username) {
		this.username = username;
	}
	
	@Override
	public Collection<GrantedAuthority> getAuthorities() {
		Set<GrantedAuthority> ga = new HashSet<GrantedAuthority>();
		for (AccountRole ar : this.accountRole) {
			ga.add(new SimpleGrantedAuthority(ar.getRole()));
		}
		return ga;
	}

	@Override
	public boolean isAccountNonExpired() {
		return this.isEnabled();
	}

	@Override
	public boolean isAccountNonLocked() {
		return this.isEnabled();
	}

	@Override
	public boolean isCredentialsNonExpired() {
		return this.isEnabled();
	}

	@Override
	public boolean isEnabled() {
		if (this.accountRole.size() > 0) {
			return true;
		}
		return false;
	}
	

}
